package com.ng.Service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;

import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.alibaba.fastjson.JSON;


import com.ng.entity.ESReqEntity;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.xml.soap.Text;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author cb
 * @Description TODO
 * @date 2023/3/5
 */
@Service
public class ContentService {
    @Autowired
   private ElasticsearchClient elasticsearchClient;
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    public List<Map<String, Object>> searchalllow() throws IOException {
        List<Map<String,Object>> results = new ArrayList<>();
        co.elastic.clients.elasticsearch.core.SearchResponse<Object> response3 = elasticsearchClient.search(s->s.index("chenbo"),Object.class);
        System.out.println(response3);
        System.out.println(response3.took());
        System.out.println(response3.hits().total().value());
        response3.hits().hits().forEach(e -> {
            System.out.println(e.source().toString());
            for (Map.Entry<String, List<String>> entry : e.highlight().entrySet()) {
                System.out.println("Key = " + entry.getKey());
                entry.getValue().forEach(System.out::println);
            }

        });

        return  results;
    }
  public  void   searchall() throws IOException {
        SearchRequest searchRequest = new SearchRequest("chenbo");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //termQuery 精确匹配
        //TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "小学");
        //matchAllQuery 匹配所有
//        MatchAllQueryBuilder matchAllQueryBuilder1 = QueryBuilders.matchAllQuery();
        searchSourceBuilder.query();
        //设置高亮
//        searchSourceBuilder.highlighter();
        //分页：
//        searchSourceBuilder.from();
//        searchSourceBuilder.size();
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("搜索结果：" + JSON.toJSONString(search.getHits()));
        //打印命中文档数据
        SearchHits hits = search.getHits();
        Arrays.stream(hits.getHits()).forEach(e -> {
            System.out.println(e.getSourceAsString());
        });
    }

    public Map<String, Object> selectqi(String pykm,String year,String stage) throws IOException {
        Map<String, Object>map=new HashMap<>();
        List<Map<String,Object>> results = new ArrayList<>();

        SearchRequest  searchRequest = new SearchRequest("join_index");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder bqb =new BoolQueryBuilder();

       bqb.must(QueryBuilders.termQuery("拼音刊名.keyword",pykm));
       bqb.must(QueryBuilders.termQuery("年.keyword",year));
        bqb.must(QueryBuilders.termQuery("期.keyword",stage));
        searchSourceBuilder.from(0);
       searchSourceBuilder.size(30);
        searchSourceBuilder.query(bqb);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // restHighLevelClient.close();
        // 解析结果
        SearchHits hits = searchResponse.getHits();

        for (SearchHit documentFields : hits.getHits()) {
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();

            sourceAsMap.put("id",documentFields.getId());
            sourceAsMap.put("index",documentFields.getIndex());
            // String jsonString = JSON.toJSONString(sourceAsMap);
            results.add(sourceAsMap);
        }
        map.put("list",results);
        /*获取分页中，总数据数*/
        map.put("totalsize",hits.getTotalHits().value);
        // 返回查询的结果
        return map;
    }

    public  Object   getesbyid(String index,String id) throws IOException {
        org.elasticsearch.action.get.GetRequest request = new GetRequest(index,id);
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString());// 打印文档内容
        System.out.println(request);// 返回的全部内容和命令是一样的
        return   response.getSource();

    }

    public Map<String, Object> search(ESReqEntity esre) throws IOException {

        Map<String, Object>map=new HashMap<>();
        List<Map<String,Object>> results = new ArrayList<>();
        List<String>syscodes=esre.getSyscodes();
        if (esre.pageIndex < 0){
            esre.pageIndex = 0;
        }
        int pageindex=esre.pageIndex;
//        co.elastic.clients.elasticsearch.core.SearchResponse<Object> response3 = elasticsearchClient.search(s -> s
//                        .index("cjfx")
//                        .query(q -> q.match(
//                                m->m
//                                        .field("篇名")
//                                        .query(FieldValue.of(keyword))
//                                )
//                        )
//                        .highlight(h->h.fields("篇名",f->f.preTags("<font color='red'>")
//                                        .postTags("</font>")
//                                )
//                        )
//                        .from(pageindex)
//                        .size(pageSize)
//                , Object.class);
//        System.out.println(response3.took());
//        System.out.println(response3.hits().total().value());
//        SearchHit hit=response3.;
//
//          List<Hit<Object>> aa=response3.hits().hits();
//        Map<String, Object> sourceAsMap=new HashMap<>();
//          List<Object>ss=new ArrayList<>();
//        response3.hits().hits().forEach(e -> {
//           System.out.println(e.source().toString());
//            System.out.println(e.highlight());
//            HighlightField bb=
////            for (Map.Entry<String, List<String>> entry : e.highlight().entrySet()) {
////                Map<String, Object> sourceAsMap=new HashMap<>();
////                sourceAsMap.put( entry.getKey(),entry.getValue());
////                results.add(sourceAsMap);
////              //  System.out.println("Key666 = " + entry.getKey());
////                //entry.getValue().forEach(System.out::println);
////            }
//
//        });
//        sourceAsMap.put("total",response3.hits().total().value());
//        sourceAsMap.put("result",ss);
//            results.add(sourceAsMap);

        SearchRequest jd_goods = new SearchRequest("join_index");
        // 创建搜索源建造者对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 条件采用：精确查询 通过keyword查字段name
       // TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("篇名", keyword);
        BoolQueryBuilder bqb =new BoolQueryBuilder();
        if(syscodes!=null&&syscodes.size()>0){
            for (String item:syscodes) {
                bqb.must(QueryBuilders.wildcardQuery("FX内容代码.keyword",item+"*"));
            }
            searchSourceBuilder.query(bqb);
        }
          if(StringUtils.isNotBlank(esre.keyword)){
              if(esre.searchfield.equals("篇名")){
                MatchQueryBuilder   matchQueryBuilder=QueryBuilders.matchQuery("篇名", esre.keyword);
                searchSourceBuilder.query(matchQueryBuilder);
              }
              else {

                  bqb.must(QueryBuilders.wildcardQuery(esre.getSearchfield()+".keyword",esre.keyword+"*"));
                  searchSourceBuilder.query(bqb);
              }

          }

       if(StringUtils.isBlank(esre.keyword)) {
           searchSourceBuilder.sort("出版日期", SortOrder.DESC);
       }
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));// 60s
        // 分页
        searchSourceBuilder.from(esre.pageIndex);
        searchSourceBuilder.size(esre.pageSize);
        searchSourceBuilder.fetchSource(new String[]{"篇名","_id",
                "文件名","拼音刊名", "光盘号", "作者","中文刊名","出版日期","中文摘要","年","期","机构","中文关键词","FX内容代码","出版单位","被引频次","下载频次","核心期刊","专辑代码"}, null);
        // 高亮
        // ....
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.fragmentSize(5); /*长度*/
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("篇名");
        /*需要highlightBuilder，前面创建好*/
        searchSourceBuilder.highlighter(highlightBuilder);

        //返回真实的命中条数,false 则最多返回10000条
        searchSourceBuilder.trackTotalHits(true);
        // 搜索源放入搜索请求中
        jd_goods.source(searchSourceBuilder);
        // 执行查询，返回结果
        SearchResponse searchResponse = restHighLevelClient.search(jd_goods, RequestOptions.DEFAULT);
       // restHighLevelClient.close();
        // 解析结果
        SearchHits hits = searchResponse.getHits();

        for (SearchHit documentFields : hits.getHits()) {
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();

            HighlightField highlightField = documentFields.getHighlightFields().get("篇名");
            if(highlightField!=null){
                String highLightSring = highlightField.getFragments()[0].toString();
                sourceAsMap.put("篇名",highLightSring);
            }
            sourceAsMap.put("id",documentFields.getId());
            sourceAsMap.put("index",documentFields.getIndex());
           // String jsonString = JSON.toJSONString(sourceAsMap);
            results.add(sourceAsMap);
        }


        map.put("list",results);
        /*获取分页中，总数据数*/
        map.put("totalsize",hits.getTotalHits().value);
        // 返回查询的结果
        return map;
    }

}
